		TITLE	XRFMAP - Copyright (c) SLR Systems 1994

		INCLUDE	MACROS
		INCLUDE	SYMBOLS
		INCLUDE	MODULES


		PUBLIC	ALLOW_XREF_MAP,DO_XREF_MAP


		.DATA

		EXTERNDEF	XOUTBUF:BYTE

		EXTERNDEF	FIRST_XREF_BLK:DWORD,PAGEWIDTH:DWORD

		EXTERNDEF	XREF_OK_SEM:GLOBALSEM_STRUCT,MODULE_GARRAY:STD_PTR_S,SYMBOL_GARRAY:STD_PTR_S
		EXTERNDEF	XREF_STUFF:ALLOCS_STRUCT


		.CODE	PASS2_TEXT

		EXTERNDEF	_capture_eax:proc
		EXTERNDEF	_release_eax:proc
		EXTERNDEF	_release_eax_bump:proc
		EXTERNDEF	TQUICK_ALPHA_XREF:PROC,HEADER_OUT:PROC,_release_minidata:proc
		EXTERNDEF	RELEASE_EAX_BUFFER:PROC,UNUSE_SYMBOLS:PROC,MOVE_SLEN:PROC,MOVE_PNAME:PROC,SPACE_OUT:PROC
		EXTERNDEF	LINE_OUT:PROC,XREF_POOL_GET:PROC,RELEASE_SEGMENT:PROC,CAPTURE_EAX:PROC,RELEASE_EAX:PROC
		EXTERNDEF	MOVE_ASCIZ_ESI_EDI:PROC,SAY_VERBOSE:PROC


WM_XREF_VARS	STRUC

QN_BUFFER_BP		DD	256K/(page_size/4) DUP(?)	;256K SYMBOLS SORTING

WM_CURNMOD_GINDEX_BP	DD	?
WM_BLK_PTR_BP		DD	?
WM_CNT_BP		DD	?
WM_PTR_BP		DD	?


WM_XREF_VARS	ENDS


FIX	MACRO	X

X	EQU	([EBP-SIZE WM_XREF_VARS].(X&_BP))

	ENDM


FIX	QN_BUFFER
FIX	WM_CURNMOD_GINDEX
FIX	WM_BLK_PTR
FIX	WM_CNT
FIX	WM_PTR


ALLOW_XREF_MAP	PROC
		;
		;
		;
if	fgh_mapthread
		BITT	_HOST_THREADED
		JZ	DO_XREF_MAP

		RELEASE	XREF_OK_SEM

		RET
endif

ALLOW_XREF_MAP	ENDP


DO_XREF_MAP	PROC
		;
		;PRINT COMPLETE GLOBAL XREF
		;
		BITT	XREF_OUT
		JZ	NO_XREF

		PUSHM	EBP,EDI,ESI,EBX

		MOV	EBP,ESP
		ASSUME	EBP:PTR WM_XREF_VARS
		SUB	ESP,SIZEOF WM_XREF_VARS

		CAPTURE	XREF_OK_SEM		;WAIT FOR .EXE AND .CV TO FINISH
						;BEFORE GRABBING CPU FOR SORT

		YIELD				;SO STOP WORKS
if	debug
		MOV	EAX,OFF XREF_MSG
		CALL	SAY_VERBOSE
endif
		XOR	ECX,ECX
		LEA	EAX,QN_BUFFER

		MOV	QN_BUFFER,ECX
		CALL	TQUICK_ALPHA_XREF	;SORT SYMBOLS AGAIN - EVEN NON-PUBLICS (IMPORTS, ETC)

		CALL	XREF_PREPROCESS		;LINK REFERENCES TOGETHER

		MOV	EAX,OFF XREF_HEADER
		CALL	HEADER_OUT

		CALL	TBLINIT

		JMP	DX_1

DX_LOOP:
		CONVERT	ECX,EAX,SYMBOL_GARRAY
		ASSUME	ECX:PTR SYMBOL_STRUCT

		CALL	OUTPUT_XREF
DX_1:
		CALL	TBLNEXT			;DS:SI IS SYMBOL, AX IS GINDEX
		JNZ	DX_LOOP
		;
		;RELEASE BLOCKS USED FOR XREF INFORMATION...
		;
if	debug
		MOV	EAX,OFF END_XREF_MSG
		CALL	SAY_VERBOSE
endif
		MOV	EAX,OFF XREF_STUFF
		push	EAX
		call	_release_minidata
		add	ESP,4

		LEA	EAX,QN_BUFFER
		CALL	RELEASE_EAX_BUFFER	;RELEASE SORTED SYMBOL POINTERS

		CALL	UNUSE_SYMBOLS		;I'M DONE WITH SYMBOL TABLE

		MOV	ESP,EBP

		POPM	EBX,ESI,EDI,EBP

NO_XREF:
		RET

DO_XREF_MAP	ENDP


OUTPUT_XREF	PROC	NEAR
		;
		;ECX IS SYMBOL
		;
		MOV	EDI,OFF XOUTBUF+1
		MOV	EBX,ECX
		ASSUME	EBX:PTR SYMBOL_STRUCT

		MOV	AL,' '
		LEA	ESI,[ECX]._S_NAME_TEXT

		MOV	[EDI-1],AL
		CALL	MOVE_ASCIZ_ESI_EDI		;OUTPUT SYMBOL TEXT

		MOV	EAX,[EBX]._S_LAST_XREF
		MOV	EBX,[EBX]._S_DEFINING_MOD

		TEST	EBX,EBX
		JZ	L1$

		ASSUME	ECX:NOTHING

		PUSH	EAX
		MOV	ECX,OFF XOUTBUF+19

		CALL	SPACE_OUT_NL		;SPACE OVER TO 'DEFINED' COLUMN, NEW-LINE IF ALREADY PAST IT

		CONVERT	EBX,EBX,MODULE_GARRAY
		ASSUME	EBX:PTR MODULE_STRUCT

		LEA	ESI,[EBX]._M_TEXT
		CALL	MOVE_ASCIZ_ESI_EDI

		POP	EAX
L1$:
		TEST	EAX,EAX
		JZ	REF_DONE

		PUSH	EAX
		MOV	ECX,OFF XOUTBUF+37

		CALL	SPACE_OUT_NL		;SPACE OVER TO REFERENCE COLUMN, NEW-LINE IF PAST IT
		;
		;NOW SEE IF ANOTHER REFERENCE
		;
		POP	ECX
L2$:
		TEST	ECX,ECX
		JZ	REF_DONE

		MOV	EAX,[ECX]		;SAVE LINK TO NEXT
		MOV	ESI,[ECX+4]

		PUSH	EAX
		CONVERT	ESI,ESI,MODULE_GARRAY
		ASSUME	ESI:PTR MODULE_STRUCT
		ADD	ESI,MODULE_STRUCT._M_TEXT

L25$:
		MOV	EDX,EDI			;STARTING DI
		MOV	ECX,PAGEWIDTH

		MOV	EBX,ESI			;START OF SYMBOL TEXT
		ADD	ECX,OFF XOUTBUF
		;
		;MOVE NAME TILL LIMIT
		;
L3$:
		MOV	AL,BYTE PTR[ESI]
		INC	ESI

		MOV	[EDI],AL
		INC	EDI

		OR	AL,AL
		JNZ	L3$

		DEC	EDI

		CMP	ECX,EDI			;DID WE EXCEED LINE WIDTH?
		JA	L4$			;NOPE, OK

		CMP	EDX,OFF XOUTBUF+37	;BUT DID WE START AT THE BEGINNING?
		JZ	L4$			;YES, SO KEEP IT ANYWAY

		MOV	EDI,EDX
		MOV	ESI,EBX

		CALL	LINE_OUT

		MOV	ECX,OFF XOUTBUF+37
		CALL	SPACE_OUT

		JMP	L25$

L4$:
		MOV	BPTR [EDI],' '
		INC	EDI

		POP	ECX
		JMP	L2$

REF_DONE:
		CALL	LINE_OUT
		RET

OUTPUT_XREF	ENDP

		ASSUME	EBX:NOTHING,ESI:NOTHING


XREF_PREPROCESS	PROC	NEAR
		;
		;SCAN LIST OF REFERENCES, BUILDING LINKED LISTS FOR EACH SYMBOL...
		;
		XOR	EAX,EAX
		MOV	WM_CURNMOD_GINDEX,EAX
		XCHG	EAX,FIRST_XREF_BLK
L0$:
		MOV	ESI,EAX
		MOV	EDX,EAX

		ADD	EDX,PAGE_SIZE-4
L1$:
		MOV	EBX,[ESI]
		ADD	ESI,4

		CMP	EBX,-1
		JZ	L5$			;SET MODULE #

		CONVERT	EBX,EBX,SYMBOL_GARRAY
		ASSUME	EBX:PTR SYMBOL_STRUCT

		MOV	EAX,8
		CALL	XREF_POOL_GET		;EAX

		MOV	ECX,[EBX]._S_LAST_XREF
		MOV	[EBX]._S_LAST_XREF,EAX

		MOV	EBX,WM_CURNMOD_GINDEX
		MOV	[EAX],ECX

		MOV	[EAX+4],EBX

L4$:
		CMP	ESI,EDX
		JNZ	L1$

		MOV	EBX,[ESI]
		LEA	EAX,[EDX - (PAGE_SIZE-4)]

		CALL	RELEASE_SEGMENT

		MOV	EAX,EBX

		OR	EAX,EAX
		JNZ	L0$
L9$:
		RET

L5$:
		CMP	ESI,EDX
		JZ	L7$
L6$:
		MOV	EAX,[ESI]
		ADD	ESI,4

		MOV	WM_CURNMOD_GINDEX,EAX

		OR	EAX,EAX
		JNZ	L4$
		;
		;MODULE 0 IS END OF XREF DATA
		;
		LEA	EAX,[EDX - (PAGE_SIZE-4)]
		CALL	RELEASE_SEGMENT
		RET

L7$:
		;
		;MODULE CHANGE ON PAGE BOUNDS
		;
		MOV	ESI,[ESI]
		LEA	EAX,[EDX - (PAGE_SIZE-4)]

		MOV	EDX,ESI
		CALL	RELEASE_SEGMENT

		ADD	EDX,PAGE_SIZE-4
		JMP	L6$

XREF_PREPROCESS	ENDP


SPACE_OUT_NL	PROC	NEAR
		;
		;NEWLINE IF GONE TOO FAR
		;
L1$:
		CMP	ECX,EDI
		JBE	L5$

		SUB	ECX,EDI
		MOV	AL,' '

		REP	STOSB

		RET

L5$:
		PUSH	ECX
		CALL	LINE_OUT

		POP	ECX
		JMP	L1$

SPACE_OUT_NL	ENDP


TBLINIT		PROC	PRIVATE

		LEA	ECX,QN_BUFFER+8		;TABLE OF BLOCKS OF INDEXES
		MOV	EAX,QN_BUFFER+4		;FIRST BLOCK

		MOV	WM_BLK_PTR,ECX		;POINTER TO NEXT BLOCK

		TEST	EAX,EAX
		JZ	L9$
		;
		MOV	ECX,PAGE_SIZE/4
		MOV	WM_PTR,EAX		;PHYSICAL POINTER TO NEXT INDEX TO PICK

		MOV	WM_CNT,ECX
		OR	AL,1
L9$:
		RET

TBLINIT 	ENDP


TBLNEXT		PROC	NEAR	PRIVATE
		;
		;GET NEXT SYMBOL INDEX IN AX, DS:SI POINTS
		;
		MOV	EDX,WM_CNT
		MOV	ECX,WM_PTR

		DEC	EDX			;LAST ONE?
		JZ	L5$

		MOV	EAX,[ECX]		;NEXT INDEX
		ADD	ECX,4

		TEST	EAX,EAX
		JZ	L9$

		MOV	WM_PTR,ECX		;UPDATE POINTER
		MOV	WM_CNT,EDX		;UPDATE COUNTER

L9$:
		RET

L5$:
		;
		;NEXT BLOCK
		;
		MOV	EAX,[ECX]
		MOV	ECX,WM_BLK_PTR

		MOV	WM_CNT,PAGE_SIZE/4

		MOV	EDX,[ECX]
		ADD	ECX,4

		MOV	WM_PTR,EDX
		MOV	WM_BLK_PTR,ECX

		TEST	EAX,EAX

		RET


TBLNEXT 	ENDP


		.CONST

XREF_HEADER	DB	SIZEOF XREF_HEADER-1,0DH,0AH,\
			'  Symbol           Defined           Referenced',\
			0dh,0ah,0dh,0ah
if	debug
XREF_MSG	DB	SIZEOF XREF_MSG-1,'Doing XREF',0DH,0AH
END_XREF_MSG	DB	SIZEOF END_XREF_MSG-1,'Finished XREF',0DH,0AH
endif

		END

